﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PerformanceUtility.GameDebugTools;
using BEPUphysics;
using BEPUphysics.Collidables;
using BEPUphysics.Collidables.MobileCollidables;
using BEPUphysics.CollisionShapes.ConvexShapes;
using BEPUphysics.DataStructures;
using BEPUphysics.Entities;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.MathExtensions;
using BEPUphysics.NarrowPhaseSystems.Pairs;
using LevelEditor.BepuTools;

namespace LevelEditor.EditorSupport
{
    public static class DebugFunctions
    {
        public static void ExitCommand(IDebugCommandHost host, string command, IList<string> arguments)
        {
            EditorComponents.Game.Exit();
        }

        public static void LoadModel(IDebugCommandHost host, string command, IList<string> arguments)
        {
            if (arguments.Count == 0)
            {
                host.EchoError("No model specified...");
            }
            for (int i = 0; i < arguments.Count; i++)
            {
                try
                {
                    int modelCount = 0;
                    for (int j = 0; j < LevelObjects.StillModels.Count; j++)
                    {
                        if (LevelObjects.StillModels[j].ID.ToUpper() == arguments[i].ToUpper() ||
                            LevelObjects.StillModels[j].ID.ToUpper() == arguments[i].ToUpper() + modelCount)
                        {
                            modelCount++;
                        }
                    }
                    LevelObjects.StillModels.Add(new EditorModels(arguments[i] + modelCount.ToString(), EditorComponents.Content.Load<Model>(arguments[i]), EditorComponents.Content.Load<Model>(arguments[i] + "_bepu"), true, true, true, arguments[i], new Vector3(0, 0, 0), new Vector3(1, 1, 1), new Vector3(MathHelper.PiOver2, 0, 0)));

                    EditorComponents.LoadShadowEffect(LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].NineModel, "Effects/ShadowEffect", EditorComponents.Content, LevelObjects.LightView, LevelObjects.LightProjection);

                    // Load bounding mesh
                    Vector3[] staticTriangleVertices;
                    int[] staticTriangleIndices;

                    TriangleMesh.GetVerticesAndIndicesFromModel(LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].NineModel, out staticTriangleVertices, out staticTriangleIndices);

                    var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].Scale, Quaternion.CreateFromRotationMatrix(Matrix.CreateRotationX(LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].Rotation.X) * Matrix.CreateRotationY(LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].Rotation.Y) * Matrix.CreateRotationZ(LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].Rotation.Z)), LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].Position));
                    //var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(LevelComponents.StillModels[LevelComponents.StillModels.Count - 1].Scale, Quaternion.CreateFromRotationMatrix(Matrix.CreateRotationX(MathHelper.PiOver2 + MathHelper.PiOver4) * Matrix.CreateRotationY(MathHelper.PiOver4 / 2)), LevelComponents.StillModels[LevelComponents.StillModels.Count - 1].Position));
                    staticMesh.Sidedness = TriangleSidedness.Counterclockwise;

                    staticMesh.Tag = LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].ID;

                    LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].Mesh = staticMesh;

                    // Add to the space
                    EditorComponents.space.Add(LevelObjects.StillModels[LevelObjects.StillModels.Count - 1].Mesh);

                    if (LevelObjects.DrawBounds)
                    {
                        EditorComponents.Game.Components.Add(new StaticModel(LevelObjects.StillModels[i].XnaModel, LevelObjects.StillModels[i].WorldMatrix, EditorComponents.Game));
                    }
                }
                catch
                {
                    host.EchoError("Could not find model " + arguments[i]);
                }
            }
        }

        public static void ListModels(IDebugCommandHost host, string command, IList<string> arguments)
        {
            if (arguments.Count == 0)
            {
                for (int i = 0; i < LevelObjects.StillModels.Count; i++)
                {
                    host.Echo(LevelObjects.StillModels[i].ID + " P: " + LevelObjects.StillModels[i].Position.ToString() + " R: " + LevelObjects.StillModels[i].Rotation.ToString() + " S: " + LevelObjects.StillModels[i].Scale.ToString());
                }
            }
            else
            {
                for (int i = 0; i < LevelObjects.StillModels.Count; i++)
                {
                    if (LevelObjects.StillModels[i].ID.ToUpper().StartsWith(arguments[0].ToUpper()))
                    {
                        host.Echo(LevelObjects.StillModels[i].ID + " P: " + LevelObjects.StillModels[i].Position.ToString() + " R: " + LevelObjects.StillModels[i].Rotation.ToString() + " S: " + LevelObjects.StillModels[i].Scale.ToString());
                    }
                }
            }
        }

        public static void SelectModels(IDebugCommandHost host, string command, IList<string> arguments)
        {
            if (arguments.Count == 0)
            {
                LevelObjects.SelectedModels.Clear();
                for (int i = 0; i < LevelObjects.StillModels.Count; i++)
                {
                    LevelObjects.SelectedModels.Add(LevelObjects.StillModels[i]);
                }
            }
            else
            {
                LevelObjects.SelectedModels.Clear();
                for (int i = 0; i < LevelObjects.StillModels.Count; i++)
                {
                    if (LevelObjects.StillModels[i].ID.ToUpper().StartsWith(arguments[0].ToUpper()))
                    {
                        LevelObjects.SelectedModels.Add(LevelObjects.StillModels[i]);
                    }
                }
            }
        }

        public static void DeleteModels(IDebugCommandHost host, string command, IList<string> arguments)
        {
            if (arguments.Count == 0)
            {
                LevelObjects.SelectedModels.Clear();
                LevelObjects.StillModels.Clear();
            }
            else
            {
                LevelObjects.SelectedModels.Clear();
                for (int i = 0; i < LevelObjects.StillModels.Count; i++)
                {
                    if (LevelObjects.StillModels[i].ID.ToUpper().StartsWith(arguments[0].ToUpper()))
                    {
                        LevelObjects.SelectedModels.Add(LevelObjects.StillModels[i]);
                    }
                }
                for (int i = 0; i < LevelObjects.SelectedModels.Count; i++)
                {
                    LevelObjects.StillModels.Remove(LevelObjects.SelectedModels[i]);
                }
                LevelObjects.SelectedModels.Clear();
            }
        }
    }
}
